<template>
	<view class="pro-tooltip" :style="{'--theme-bg-color': color}">
		<!-- #ifdef APP-PLUS -->
		<view class="pro-tooltip-content" @longpress="handleClick" @touchend="handleTouchEnd">
			<slot></slot>
			<view class="pro-tooltip-popper" @click.stop="() => {}" :style="[style,
				{
					visibility: isShow ? 'visible' : 'hidden',
					color: color === 'white' ? '' : '#fff',
					maxWidth: maxWidth + 'px',
					minWidth: minWidth ? (minWidth + 'px') : undefined,
					boxShadow: color === 'white' ? '0 3px 6px -4px #0000001f, 0 6px 16px #00000014, 0 9px 28px 8px #0000000d' : ''
				}]">
				<slot name="content">
					<rich-text v-if="richText" :nodes="content"></rich-text>
					<text v-else>{{ content }}</text>
				</slot>
				<view class="pro-popper-icon" :style="[arrowStyle]" :class="[{
				'pro-popper-up': placement.indexOf('bottom') === 0,
				'pro-popper-arrow': placement.indexOf('top') === 0,
				'pro-popper-right': placement.indexOf('right') === 0,
				'pro-popper-left': placement.indexOf('left') === 0
			}]"></view>
			</view>
		</view>
		<!-- #endif -->
		<!-- #ifdef H5 -->
		<view class="pro-tooltip-content" @click="handleTipClick">
			<slot></slot>
			<view class="pro-tooltip-popper" @click.stop="() => {}" :style="[style, {
				visibility: isShow ? 'visible' : 'hidden',
				color: color === 'white' ? '' : '#fff',
				maxWidth: maxWidth + 'px',
				minWidth: minWidth ? (minWidth + 'px') : undefined,
				boxShadow: color === 'white' ? '0 3px 6px -4px #0000001f, 0 6px 16px #00000014, 0 9px 28px 8px #0000000d' : ''
			}]">
				<slot name="content">
					<rich-text v-if="richText" :nodes="content"></rich-text>
					<text v-else>{{ content }}</text>
				</slot>
				<view class="pro-popper-icon" :style="[arrowStyle]" :class="[{
					'pro-popper-up': placement.indexOf('bottom') === 0,
					'pro-popper-arrow': placement.indexOf('top') === 0,
					'pro-popper-right': placement.indexOf('right') === 0,
					'pro-popper-left': placement.indexOf('left') === 0
				}]"></view>
			</view>
		</view>
		<!-- #endif -->
	</view>
</template>

<script>
	/**
	 * ProTooltip 文字提示气泡框
	 * @author denglei
	 * @description 文字提示--当文字过多没法全部显示的时候，使用tooltip组件，以气泡的方式进行展示，长按文本的时候展示气泡，按住不动，气泡不会消失，之后松开了，气泡才会在2s后自动消失
	 * @tutorial 
	 * @property {Boolean} visible =[true | false] 控制tooltip展示，隐藏
	 * @property {String} color = [#fff] 字体颜色
	 * @property {String} placement = [top|top-start|top-end|bottom|bottom-start|bottom-end|right|right-start|right-end|left|left-start|left-end] tooltip的出现位置
	 * @property {String} content = [] 文本内容
	 * @property {Boolean} show = [true | false] 是否展示tooltip
	 * @property {Boolean} richText = [true | false] 内容是否是富文本		
	 * @property {Number} maxWidth	tooltip气泡的最大宽度
	 * @example 	<pro-tooltip content="测试文本">测试文本</pro-tooltip>
	 *注意：因为uniapp 中小程序中没有window对象，需手动调用 关闭
        第一种办法关闭：this.$refs.tooltip.close()
          第二种办法关闭：visible.sync = false
	 */
	export default {
		name: 'ProTooltip',
		props: {
			visible: Boolean,
			color: {
				type: String,
				default: '#FFF'
			},
			placement: {
				type: String,
				default: 'top'
			},
			// 文本内容
			content: {
				type: String,
				default: ''
			},
			// 是否展示
			show: {
				type: Boolean,
				default: false
			},
			// 是否是富文本
			richText: {
				type: Boolean,
				default: false
			},
			// tooltip气泡的最大宽度
			maxWidth: {
				type: Number,
				default: 400
			},
			// tooltip气泡的最小宽度
			minWidth: Number,
			// 显示时间
			timeout: {
				type: Number,
				default: 1500
			}
		},

		data() {
			return {
				isShow: this.visible,
				title: 'Hello',
				arrowLeft: 0,
				query: null,
				style: {},
				arrowStyle: {}
			};
		},
		onLoad() {},
		watch: {
			isShow: {
				handler(val) {
					this.$emit('update:visible', val);
				},
				immediate: true
			},
			visible: {
				handler(val) {
					if (val) {
						this.$nextTick(() => {
							this.getPosition();
						});
					}
					this.isShow = val;
				},
				immediate: true
			}
		},
		mounted() {
			this.getPosition();
		},
		methods: {
			close() {
				this.isShow = false;
			},
			handleTouchEnd() {
				setTimeout(() => {
					this.isShow = false;
				}, this.timeout); //显示1.5秒后自动隐藏
			},
			async handleClick() {
				if (this.isShow) {
					return (this.isShow = false);
				}
				await this.getPosition();
				this.isShow = true;
			},
			async handleTipClick() {
				if (this.isShow) {
					return (this.isShow = false);
				}
				await this.getPosition();
				this.isShow = true;
				setTimeout(() => {
					this.isShow = false;
				}, this.timeout); //显示1.5秒后自动隐藏
			},
			getPosition() {
				return new Promise(resolve => {
					uni
						.createSelectorQuery()
						.in(this)
						.selectAll('.pro-tooltip-content,.pro-tooltip-popper')
						.boundingClientRect(async data => {
							let {
								left,
								bottom,
								right,
								top,
								width,
								height
							} = data[0];
							let obj1 = data[1];
							let objStyle = {};
							let objStyle1 = {};
							switch (this.placement) {
								case 'top':
									if (obj1.width > width) {
										objStyle.left = `-${(obj1.width - width) / 2}px`;
									} else {
										objStyle.left = `${Math.abs(obj1.width - width) / 2}px`;
									}

									objStyle.bottom = `${height + 8}px`;
									objStyle1.left = obj1.width / 2 - 6 + 'px';
									break;
								case 'top-start':
									objStyle.left = `0px`;
									objStyle.bottom = `${height + 8}px`;
									break;
								case 'top-end':
									objStyle.right = `0px`;
									objStyle.bottom = `${height + 8}px`;
									objStyle1.right = `8px`;
									break;
								case 'bottom':
									if (obj1.width > width) {
										objStyle.left = `-${(obj1.width - width) / 2}px`;
									} else {
										objStyle.left = `${Math.abs(obj1.width - width) / 2}px`;
									}
									objStyle.top = `${height + 8}px`;
									objStyle1.left = obj1.width / 2 - 6 + 'px';
									break;
								case 'bottom-start':
									objStyle.left = `0px`;
									objStyle.top = `${height + 8}px`;
									objStyle1.left = `8px`;
									break;

								case 'bottom-end':
									objStyle.right = `0px`;
									objStyle.top = `${height + 8}px`;
									objStyle1.right = `8px`;
									break;

								case 'right':
									objStyle.left = `${width + 8}px`;
									if (obj1.height > height) {
										objStyle.top = `-${(obj1.height - height) / 2}px`;
									} else {
										objStyle.top = `${Math.abs((obj1.height - height) / 2)}px`;
									}

									objStyle1.top = `${obj1.height / 2 - 6}px`;
									break;
								case 'right-start':
									objStyle.left = `${width + 8}px`;
									objStyle.top = `0px`;
									objStyle1.top = `8px`;
									break;

								case 'right-end':
									objStyle.left = `${width + 8}px`;
									objStyle.bottom = `0px`;
									objStyle1.bottom = `8px`;
									break;

								case 'left':
									objStyle.right = `${width + 8}px`;

									if (obj1.height > height) {
										objStyle.top = `-${(obj1.height - height) / 2}px`;
									} else {
										objStyle.top = `${Math.abs((obj1.height - height) / 2)}px`;
									}

									objStyle1.top = `${obj1.height / 2 - 6}px`;
									break;

								case 'left-start':
									objStyle.right = `${width + 8}px`;
									objStyle.top = `0px`;
									objStyle1.top = `8px`;
									break;

								case 'left-end':
									objStyle.right = `${width + 8}px`;
									objStyle.bottom = `0px`;
									objStyle1.bottom = `8px`;
									break;
							}
							this.style = objStyle;
							// 三角形箭头
							this.arrowStyle = objStyle1;
							resolve();
						})
						.exec();
				});
			}
		}
	};
</script>

<style lang="scss" scoped>
	$theme-bg-color: #333;

	.pro-tooltip {
		position: relative;
	}

	.pro-tooltip-content {
		position: relative;
		height: 100%;
		display: inline-block;
	}

	.pro-tooltip-popper {
		visibility: hidden;
		position: absolute;
		display: block;
		margin-top: 6rpx;
		border-radius: 8rpx;
		padding: 20rpx;
		min-width: 200rpx;
		max-width: 600rpx;
		word-wrap: break-word;
		white-space: wrap;
		z-index: 9999;
		font-size: 32rpx;
		line-height: 44rpx;
		background: $theme-bg-color;
	}

	.pro-popper-icon {
		width: 0;
		height: 0;
		z-index: 9;
		position: absolute;
	}

	.pro-popper-arrow {
		bottom: -5px;
		/* transform-origin: center top; */
		border-left: 6px solid transparent;
		border-right: 6px solid transparent;
		border-top: 6px solid $theme-bg-color;
	}

	.pro-popper-right {
		border-top: 6px solid transparent;
		border-bottom: 6px solid transparent;
		border-right: 6px solid $theme-bg-color;
		left: -5px;
	}

	.pro-popper-left {
		border-top: 6px solid transparent;
		border-bottom: 6px solid transparent;
		border-left: 6px solid $theme-bg-color;
		right: -5px;
	}

	.pro-popper-up {
		border-left: 6px solid transparent;
		border-right: 6px solid transparent;
		border-bottom: 6px solid $theme-bg-color;
		top: -5px;
	}
</style>